package com.iwop.moto.utils.stringUtil;

import java.text.SimpleDateFormat;
import java.util.Random;

public final class SequenceUtil {
    public static  SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); //24小时制
    public static Random rd = new Random();
    /**
     * 单元测试
     * @param args
     */
    public static void main(String[] args){
        //System.out.println(Serial(""));
        // System.out.println(getTimeMillisSequence());
        //for(int i = 0 ; i<100;i++){
            System.out.println(Serial("Moto-"));
        //}
        //System.out.println(SerialID(""));
    }

    public static String Serial(){
        return  sdf.format(System.currentTimeMillis()) + nextInt(1,999999);
    }

    public static String Serial(String type){
        return type + sdf.format(System.currentTimeMillis()) + nextInt(1,999999);
    }



    public static String SerialID(String type){
        return type + sdf.format(System.currentTimeMillis()) + nextInt(1,99);
    }

    /**
     * @return 形如 yyyyMMddHHmmssSSS-Z0000019558195832297 的(38位)保证唯一的递增的序列号字符串，
     * 主要用于数据库的主键，方便基于时间点的跨数据库的异步数据同步。
     * 前半部分是currentTimeMillis，后半部分是nanoTime（正数）补齐20位的字符串，
     * 如果通过System.nanoTime()获取的是负数，则通过nanoTime = nanoTime+Long.MAX_VALUE+1;
     * 转化为正数或零。
     */
    public static String getTimeMillisSequence(){
        long nanoTime = System.nanoTime();
        String preFix="";
        if (nanoTime<0){
            preFix="A";//负数补位A保证负数排在正数Z前面,解决正负临界值(如A9223372036854775807至Z0000000000000000000)问题。
            nanoTime = nanoTime+Long.MAX_VALUE+1;
        }else{
            preFix="Z";
        }
        String nanoTimeStr = String.valueOf(nanoTime);

        int difBit=String.valueOf(Long.MAX_VALUE).length()-nanoTimeStr.length();
        for (int i=0;i<difBit;i++){
            preFix = preFix+"0";
        }
        nanoTimeStr = preFix+nanoTimeStr;
        String timeMillisSequence=sdf.format(System.currentTimeMillis())+"-"+nanoTimeStr;

        return timeMillisSequence;
    }

    /**
     * 获取随机数范围
     * @param min 1
     * @param max 9999
     */
    public static String nextInt(final int min, final int max){
       int tmp = Math.abs(rd.nextInt());
       int xLength = String.valueOf(max).length();
       int result =  tmp % (max - min + 1) + min;
       return String.format("%0"+xLength+"d", result);
    }


    /**自定义进制(0,1没有加入,容易与o,l混淆)*/
    private static final char[] r = new char[] { 'Q', 'w', 'E', '8', 'a', 'S', '2', 'd', 'Z', 'x', '9', 'c', '7', 'p', 'O', '5', 'i', 'K', '3', 'm', 'j', 'U', 'f', 'r', '4', 'V', 'y', 'L', 't', 'N', '6', 'b', 'g', 'H' };
    /**自动补全组(不能与自定义进制有重复)*/
    private static final char[] b = new char[] { 'q', 'W', 'e', 'A', 's', 'D', 'z', 'X', 'C', 'P', 'o', 'I', 'k', 'M', 'J', 'u', 'F', 'R', 'v', 'Y', 'T', 'n', 'B', 'G', 'h' };
    /**进制长度*/
    private static final int l = r.length;
    /**序列最小长度*/
    private static final int s = 8;
    /**
     * 根据ID生成八位随机推广码
     * @return 随机码
     */
    public static String Promotion( ) {
        long num = Math.abs(rd.nextInt());
        char[] buf = new char[32];
        int charPos = 32;
        while ((num / l) > 0) {
            buf[--charPos] = r[(int) (num % l)];
            num /= l;
        }
        buf[--charPos] = r[(int) (num % l)];
        String str = new String(buf, charPos, (32 - charPos));
        //不够长度的自动随机补全
        if (str.length() < s) {
            StringBuffer sb = new StringBuffer();

            for (int i = 0; i < s - str.length(); i++) {
                sb.append(b[rd.nextInt(24)]);
            }
            str += sb.toString();
        }
        return str;
    }

    public static String Promotion( int s ) {
        long num = Math.abs(rd.nextInt());
        char[] buf = new char[32];
        int charPos = 32;
        while ((num / l) > 0) {
            buf[--charPos] = r[(int) (num % l)];
            num /= l;
        }
        buf[--charPos] = r[(int) (num % l)];
        String str = new String(buf, charPos, (32 - charPos));
        //不够长度的自动随机补全
        if (str.length() < s) {
            StringBuffer sb = new StringBuffer();

            for (int i = 0; i < s - str.length(); i++) {
                sb.append(b[rd.nextInt(24)]);
            }
            str += sb.toString();
        }
        return str;
    }
}

